package dao

import (
	"context"
	"coolcar/shared/id"
	mgo "coolcar/shared/mongo"
	"coolcar/shared/mongo/objid"
	"fmt"

	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
)

// Mongo defines a mongo dao.
type Mongo struct {
	col *mongo.Collection
}

// NewMongo creates a mongo dao.
func NewMongo(db *mongo.Database) *Mongo {
	return &Mongo{
		col: db.Collection("blob"),
	}
}

// BlobRecord defines a blob record.
type BlobRecord struct {
	mgo.IDField `bson:"inline"`
	AccountID   string `bson:"accountid"`
	Path        string `bson:"path"`
}

// CreateBlob creates a blob record.
func (m *Mongo) CreateBlob(ctx context.Context, aid id.AccountID) (*BlobRecord, error) {
	br := &BlobRecord{
		AccountID: aid.String(),
	}
	objID := mgo.NewObjID()
	br.ID = objID

	// 就好像给accountID建了一个目录，每个account有一个自己的目录，目录下有他的文件，文件名称就是objID。
	// 对象存储都是不需要建目录的，只要"%s/%s"这么写就会自动建目录。
	br.Path = fmt.Sprintf("%s/%s", aid.String(), objID.Hex())

	_, err := m.col.InsertOne(ctx, br)
	if err != nil {
		return nil, err // 直接返回数据err，上层可能还要处理。
	}

	return br, nil
}

// GetBlob gets a blob record.
func (m *Mongo) GetBlob(ctx context.Context, bid id.BlobID) (*BlobRecord, error) {
	objID, err := objid.FromID(bid)
	if err != nil {
		return nil, fmt.Errorf("invalid object id: %v", err)
	}
	res := m.col.FindOne(ctx, bson.M{
		mgo.IDFieldName: objID,
	})

	if err := res.Err(); err != nil {
		return nil, err
	}

	var br BlobRecord
	err = res.Decode(&br)
	if err != nil {
		return nil, fmt.Errorf("cannot decode result: %v", err)
	}

	return &br, nil
}
